package com.example.apidocserver.infrastructure.config.security;

import com.example.apidocserver.infrastructure.constants.UserConstants;
import com.example.apidocserver.infrastructure.util.CryptUtils;
import com.example.apidocserver.infrastructure.util.user.CurrentUser;
import com.example.apidocserver.infrastructure.util.IPUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

/**
 * 登录参数处理类
 *
 * @author luduanxu
 */
@Slf4j
public class LoginFilter extends UsernamePasswordAuthenticationFilter {
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        Map<String, Object> loginData;
        try (InputStream is = request.getInputStream()) {
            loginData = new ObjectMapper().readValue(is, Map.class);
        } catch (IOException e) {
            log.error("Error reading login data from request", e);
            throw new AuthenticationServiceException("Failed to read login data from request.", e);
        }

        String username = (String) loginData.getOrDefault(getUsernameParameter(), "");
        String password = (String) loginData.getOrDefault(getPasswordParameter(), "");
        Integer identityType = (Integer) loginData.getOrDefault(UserConstants.IDENTITY_TYPE, 1);

        if (UserConstants.IDT_NAME_PW.equals(identityType)) {
            password = CryptUtils.decrypt(password, username + ".this_pw");
        }

        UserDetailsImpl userDetails = new UserDetailsImpl();
        userDetails.setUserIp(IPUtils.getIpAddr()).setIdentifier(username).setCredential(password).setIdentifierType(identityType);
        CurrentUser.setUser(userDetails);
        if (UserConstants.IDT_TOURISTS.equals(identityType)) {
            userDetails.setIdentifier(userDetails.getUserIp()).setCredential(userDetails.getUserIp());
        }

        log.info("username: {}, pw: {}", userDetails.getIdentifier(), userDetails.getCredential());

        UsernamePasswordAuthenticationToken authRequest =
                new UsernamePasswordAuthenticationToken(userDetails.getIdentifier().trim(), userDetails.getCredential().trim());

        setDetails(request, authRequest);
        return this.getAuthenticationManager().authenticate(authRequest);
    }
}
